#include "IO.h"
#include "TinyXML/tinyxml.h"
#include "ChineseEnglishMapping.h"
#include <QDebug>
#include <QVBoxLayout>
#include <QSplitter>

IO::IO()
{

}

void IO::InitUI(const QString &fileName, QList<QPair<QWidget *, QString> > &widgets, QMap<int, QList<TableWidgetForm *> > &m_pTableWidgetFormMap)
{
    QString filePath = QString("%1/config/%2/%3")
            .arg(COMMONS->XmlPath)
            .arg(COMMONS->MachType)
            .arg(fileName);
    IOConnectStr _IOConnectStr;
    QList<QList<portstruct>> portstructList;
    Analysis(filePath, _IOConnectStr, portstructList);

    //添加第一个表
    QWidget* widget = new QWidget;
    QVBoxLayout *layout = new QVBoxLayout(widget);
    QSplitter *splitter = new QSplitter(Qt::Vertical, widget);
    splitter->setChildrenCollapsible(false);
    layout->addWidget(splitter);
    widgets.append(qMakePair(widget,QStringLiteral("tab0")));

    TableWidgetForm* _TableWidgetForm = new TableWidgetForm(widget);
    splitter->addWidget(_TableWidgetForm);
    _TableWidgetForm->setGroupBoxTitle(QString("%1_0").arg(fileName.left(fileName.size()-4)));

    //获取表头
    _TableWidgetForm->setTableWidgetHeaderLabels(COMMONS->getTableWidgetHeadLabels(fileName,_IOConnectStr.toFieldNames().split(',')));
    _TableWidgetForm->setTableWidgetHeaderType(_IOConnectStr.toFieldTypes());

    _TableWidgetForm->getTableWidget()->setRowCount(1);
    _TableWidgetForm->getTableWidget()->setItem(0, 0, new QTableWidgetItem(_IOConnectStr.name));
    _TableWidgetForm->getTableWidget()->setItem(0, 1, new QTableWidgetItem(_IOConnectStr.type));

    m_pTableWidgetFormMap.insert(0,  QList<TableWidgetForm*>() << _TableWidgetForm);

    for(int i = 0;i<portstructList.size();i++)
    {
        TableWidgetForm* _TableWidgetForm = new TableWidgetForm(widget);
        splitter->addWidget(_TableWidgetForm);
        _TableWidgetForm->setGroupBoxTitle(QString("%1_%2").arg(fileName.left(fileName.size()-4)).arg(i+1));

        portstruct _portstructtemp;
        _TableWidgetForm->setTableWidgetHeaderLabels(COMMONS->getTableWidgetHeadLabels(fileName,_portstructtemp.toFieldNames().split(',')));
        _TableWidgetForm->setTableWidgetHeaderType(_portstructtemp.toFieldTypes());

        for(int j = 0;j<portstructList.at(i).size();j++)
        {
            portstruct _portstruct = portstructList.at(i).at(j);
            int rowCount = _TableWidgetForm->getTableWidget()->rowCount();
            _TableWidgetForm->getTableWidget()->setRowCount(rowCount+1);
            _TableWidgetForm->getTableWidget()->setItem(rowCount, 0, new QTableWidgetItem(_portstruct.chs));
            _TableWidgetForm->getTableWidget()->item(rowCount,0)->setData(Qt::UserRole,_portstruct.id);
            _TableWidgetForm->getTableWidget()->setItem(rowCount, 1, new QTableWidgetItem(QString("%1").arg(_portstruct.logic)));
            _TableWidgetForm->getTableWidget()->setItem(rowCount, 2, new QTableWidgetItem(QString("%1").arg(_portstruct.phyid)));
            _TableWidgetForm->getTableWidget()->setItem(rowCount, 3, new QTableWidgetItem(QString("%1").arg(_portstruct.board_id)));
        }
        QList<TableWidgetForm*> temp = m_pTableWidgetFormMap.value(0);
        m_pTableWidgetFormMap.insert(0,  temp << _TableWidgetForm);
    }
}

bool IO::SaveUI(const QString &fileName, const QMap<int, QList<TableWidgetForm *> > &m_pTableWidgetFormMap)
{
    QString filePath = QString("%1/config/%2/%3")
            .arg(COMMONS->XmlPath)
            .arg(COMMONS->MachType)
            .arg(fileName);
    if(m_pTableWidgetFormMap.count() == 1)
    {
        IOConnectStr _IOConnectStr;
        QList<QList<portstruct> > portstructList;

        TableWidgetForm* _TableWidgetForm = m_pTableWidgetFormMap.value(0).at(0);
        if(_TableWidgetForm)
        {
            _IOConnectStr.name = _TableWidgetForm->getTableWidget()->item(0, 0)->text();
            _IOConnectStr.type = _TableWidgetForm->getTableWidget()->item(0, 1)->text();
        }

        for (int i = 1;i<m_pTableWidgetFormMap.value(0).size();i++)
        {
            TableWidgetForm* _TableWidgetForm = m_pTableWidgetFormMap.value(0).at(i);
            if(_TableWidgetForm)
            {
                QList<portstruct> _portstructs;
                for (int k = 0;k<_TableWidgetForm->getTableWidget()->rowCount();k++)
                {
                    portstruct _portstruct;
                    _portstruct.id = _TableWidgetForm->getTableWidget()->item(k,0)->data(Qt::UserRole).toInt();
                    _portstruct.chs = _TableWidgetForm->getTableWidget()->item(k,0)->text();
                    _portstruct.logic = _TableWidgetForm->getTableWidget()->item(k,1)->text().toInt();
                    _portstruct.phyid = _TableWidgetForm->getTableWidget()->item(k,2)->text().toInt();
                    _portstruct.board_id = _TableWidgetForm->getTableWidget()->item(k,3)->text().toInt();
                    _portstructs.append(_portstruct);
                }
                portstructList.append(_portstructs);
            }
        }
        SaveXml(filePath,_IOConnectStr,portstructList);
        return true;
    }
    return false;
}

void IO::Analysis(const QString &path, IOConnectStr &_IOConnectStr, QList<QList<portstruct> > &portstructList)
{
    TiXmlDocument* xmlDocument = new TiXmlDocument();
    if(!xmlDocument->LoadFile(path.toStdString().c_str()))
    {
        qDebug() << xmlDocument->ErrorDesc();
        delete xmlDocument;
        return;
    }

    //查找xml文件中第一个名为Alarms的节点
    TiXmlElement* rootElement = xmlDocument->FirstChildElement("IO");
    if(rootElement == nullptr) //节点不存在
    {
        qDebug() << xmlDocument->ErrorDesc();
        delete xmlDocument;
        return;
    }

    if(rootElement)
    {
        TiXmlElement* ConnectStrElement = rootElement->FirstChildElement("ConnectStr");
        if(ConnectStrElement != nullptr)
        {
            _IOConnectStr.name = ConnectStrElement->Attribute("name");
            _IOConnectStr.type = ConnectStrElement->Attribute("type");
        }

        TiXmlElement* outputElement = rootElement->FirstChildElement("output");
        if(outputElement != nullptr)
        {
            QList<portstruct> _portstructs;
            for (TiXmlElement* portElement = outputElement->FirstChildElement("port");
                 portElement != nullptr; portElement = portElement->NextSiblingElement("port")) {
                if(portElement != nullptr)
                {
                    portstruct _portstruct;
                    portElement->QueryIntAttribute("id", &_portstruct.id);
                    _portstruct.chs = portElement->Attribute("chs");
                    portElement->QueryIntAttribute("logic", &_portstruct.logic);
                    portElement->QueryIntAttribute("phyid", &_portstruct.phyid);
                    portElement->QueryIntAttribute("board_id", &_portstruct.board_id);
                    _portstructs.append(_portstruct);
                }
            }
            portstructList.append(_portstructs);
        }

        TiXmlElement* inputElement = rootElement->FirstChildElement("input");
        if(inputElement != nullptr)
        {
            QList<portstruct> _portstructs;
            for (TiXmlElement* portElement = inputElement->FirstChildElement("port");
                 portElement != nullptr; portElement = portElement->NextSiblingElement("port")) {
                if(portElement != nullptr)
                {
                    portstruct _portstruct;
                    portElement->QueryIntAttribute("id", &_portstruct.id);
                    _portstruct.chs = portElement->Attribute("chs");
                    portElement->QueryIntAttribute("logic", &_portstruct.logic);
                    portElement->QueryIntAttribute("phyid", &_portstruct.phyid);
                    portElement->QueryIntAttribute("board_id", &_portstruct.board_id);
                    _portstructs.append(_portstruct);
                }
            }
            portstructList.append(_portstructs);
        }
    }
}

bool IO::SaveXml(const QString &path, const IOConnectStr &_IOConnectStr, const QList<QList<portstruct> > &portstructList)
{
    TiXmlDocument* xmlDocument = new TiXmlDocument();
    if(!xmlDocument->LoadFile(path.toStdString().c_str()))
    {
        qDebug() << xmlDocument->ErrorDesc();
        delete xmlDocument;
        return false;
    }

    TiXmlElement* rootElement = xmlDocument->FirstChildElement("IO");
    if(rootElement == nullptr) //节点不存在
    {
        qDebug() << xmlDocument->ErrorDesc();
        delete xmlDocument;
        return false;
    }

    if(rootElement)
    {
        TiXmlElement* ConnectStrElement = rootElement->FirstChildElement("ConnectStr");
        if(ConnectStrElement != nullptr)
        {
            ConnectStrElement->SetAttribute("name", _IOConnectStr.name.toStdString().c_str());
            ConnectStrElement->SetAttribute("type", _IOConnectStr.type.toStdString().c_str());
        }

        TiXmlElement* outputElement = rootElement->FirstChildElement("output");
        if(outputElement != nullptr)
        {
            QList<portstruct> _portstructs;
            for (TiXmlElement* portElement = outputElement->FirstChildElement("port");
                 portElement != nullptr; portElement = portElement->NextSiblingElement("port")) {
                if(portElement != nullptr)
                {
                    outputElement->RemoveChild(portElement);
                }
            }
            if(portstructList.size() > 0)
            {
                for (auto _portstruct : portstructList.at(0))
                {
                    //元素类
                    TiXmlElement* ChildxmlElement = new TiXmlElement("port");
                    ChildxmlElement->SetAttribute("id", _portstruct.id);
                    ChildxmlElement->SetAttribute("chs", _portstruct.chs.toStdString().c_str());
                    ChildxmlElement->SetAttribute("logic", _portstruct.logic);
                    ChildxmlElement->SetAttribute("phyid", _portstruct.phyid);
                    ChildxmlElement->SetAttribute("board_id", _portstruct.board_id);
                    outputElement->LinkEndChild(ChildxmlElement);
                }
            }
        }

        TiXmlElement* inputElement = rootElement->FirstChildElement("input");
        if(inputElement != nullptr)
        {
            QList<portstruct> _portstructs;
            for (TiXmlElement* portElement = inputElement->FirstChildElement("port");
                 portElement != nullptr; portElement = portElement->NextSiblingElement("port")) {
                if(portElement != nullptr)
                {
                    inputElement->RemoveChild(portElement);
                }
            }
            if(portstructList.size() > 1)
            {
                for (auto _portstruct : portstructList.at(1))
                {
                    //元素类
                    TiXmlElement* ChildxmlElement = new TiXmlElement("port");
                    ChildxmlElement->SetAttribute("id", _portstruct.id);
                    ChildxmlElement->SetAttribute("chs", _portstruct.chs.toStdString().c_str());
                    ChildxmlElement->SetAttribute("logic", _portstruct.logic);
                    ChildxmlElement->SetAttribute("phyid", _portstruct.phyid);
                    ChildxmlElement->SetAttribute("board_id", _portstruct.board_id);
                    inputElement->LinkEndChild(ChildxmlElement);
                }
            }
        }
    }
    //保存
    xmlDocument->SaveFile(path.toStdString().c_str());

    delete xmlDocument;
    return true;
}
